package com.mastercard.assets.web.forms.process;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.upload.FormFile;

import com.mastercard.assets.MasterCardException;
import com.mastercard.assets.flows.FlowUtil;
import com.mastercard.assets.flows.process.FlowProcessContext;
import com.mastercard.assets.flows.process.FlowProcessInit;
import com.mastercard.assets.flows.process.FlowProcessPost;
import com.mastercard.assets.flows.process.FlowProcessPrevious;
import com.mastercard.assets.flows.process.FlowProcessResult;
import com.mastercard.assets.flows.to.FlowDataTO;
import com.mastercard.assets.flows.to.FlowPreimplementationTO;
import com.mastercard.assets.jpa.TblAsset;
import com.mastercard.assets.jpa.TblFlujo;
import com.mastercard.assets.jpa.TblForma;
import com.mastercard.assets.jpa.TblPreimplementacion;
import com.mastercard.assets.jpa.TblPreimplementacionCotiza;
import com.mastercard.assets.jpa.TblPreimplementacionCotizacionServicio;
import com.mastercard.assets.jpa.TblServicio;
import com.mastercard.assets.jpa.TblTarea;
import com.mastercard.assets.jpa.TblTareaPreimplementacion;
import com.mastercard.assets.util.MCUtil;
import com.mastercard.assets.util.dao.MasterCardDAO;
import com.mastercard.assets.web.struts.forms.FlowProcessForm;
import com.mastercard.assets.web.util.to.UserLogin;

public class PreimplementationEmitirBoletosFormProcess
	implements
		FlowProcessInit , 
		FlowProcessPrevious , 
		FlowProcessPost
{
	public FlowProcessResult loadFormData( FlowProcessContext ctx )
		throws
			MasterCardException
	{
		TblTareaPreimplementacion tblTareaPreimplementacion = ctx.getTblTareaPreimplementacion( ) ;
		
		TblPreimplementacion tblPreimplementacion = tblTareaPreimplementacion.getTblPreimplementacion( ) ;
		
		TblFlujo tblFlujo = tblPreimplementacion.getTblFlujo( ) ;
		
		TblAsset asset = tblTareaPreimplementacion.getTblAsset( ) ;
		
		int cveFlujo = tblFlujo.getCveFlujo( ) ;
		int cvePreimplementacion = tblPreimplementacion.getCvePreimplementacion( ) ;
		int cveTareaPreimplementacion = tblTareaPreimplementacion.getCveTareaPreimplementacion( ) ;
		int cveAsset = asset.getCveAsset( ) ;
		
		// esta es la segunda tarea del flujo, y siendo que la primera tarea del flujo solo tiene una salida, y que 
		// este flujo se ejecuta siempre con el mismo asset, entonces busca el registro de TblTareaPreimplementacion
		// con la primer tarea, el asset del registro TblTareaPreimplementacion propio y el flujo propio y que ya se
		// encuentre ejecutado.
		TblTarea firstWork = MasterCardDAO.getFirstWorkInFlow( cveFlujo ) ;
		
		int cveFirstWork = firstWork.getCveTarea( ) ;
		
		// busca la tareapreimplementacion de acuerdo a sus datos
		List< TblTareaPreimplementacion > tblTareaPreimplementacionAnteriores = MasterCardDAO.findTareaPreimplementacionByPreimplementacionAndTareaAndAssetAndExecutedAndStatusAndAllActive( 
								cvePreimplementacion , 
								cveAsset , 
								cveFirstWork , 
								1 ) ;
		
		TblTareaPreimplementacion tblTareaPreimplementacionInicial = null ;
		
		// en caso de que haya varias, toma la primera, con la que se creo la cotizacion
		if( tblTareaPreimplementacionAnteriores != null && tblTareaPreimplementacionAnteriores.size( ) > 0 )
			tblTareaPreimplementacionInicial = tblTareaPreimplementacionAnteriores.get( 0 ) ;
		
		// cotizacion relacionada con la tareaPreimplementacion
		TblPreimplementacionCotiza cotizacion = null ;
		
		// datos a enviar
		FlowPreimplementationTO to = new FlowPreimplementationTO( ) ;
		
		to.setWithFile( true ) ;
		to.setCveFlow( tblFlujo.getCveFlujo( ) ) ;
		to.setFlow( tblFlujo ) ;
		to.setTblTareaPreimplementacion( tblTareaPreimplementacion ) ;
		to.setTareaPreimplementacionAnterior( tblTareaPreimplementacionInicial ) ;
		
		// en caso de que sea diferente de null
		if( tblTareaPreimplementacionInicial != null )
		{
			// crea la Cotizacionwraper
			CotizacionWraper cotizacionWraper = new CotizacionWraper( ) ;
			
			// toma todos los servicios relacionados con la tarea
			List< TblPreimplementacionCotiza > tblPreimplementacionCotizas = tblTareaPreimplementacionInicial.getTblPreimplementacionCotizas( ) ;
			
			// deberia haber solamente una cotizacion por tareaPreimplementacion
			// en caso de que haya cotizaciones...
			if( tblPreimplementacionCotizas != null && tblPreimplementacionCotizas.size( ) > 0 )
				// toma el primero
				cotizacion = tblPreimplementacionCotizas.get( 0 ) ;
			
			// lista de servicios de la cotizacion
			List< TblPreimplementacionCotizacionServicio > serviciosCotizacion = cotizacion.getTblPreimplementacionCotizacionServicios( ) ;
			
			// toma los servicios activos
			List< TblServicio > serviciosActivos = MasterCardDAO.getAllActiveServices( ) ;
			
			// recorre los servicios
			for( TblServicio servicio : serviciosActivos )
			{
				int cveServicio = servicio.getCveServicio( ) ;
				
				boolean seEncuentra = false ;
				TblPreimplementacionCotizacionServicio servicioEnCotizacion = null ;
				
				// revisa si el servicio ya se encuentra en la cotizacion
				for( TblPreimplementacionCotizacionServicio servicioCotizacion : serviciosCotizacion )
				{
					// revisa si es igual el servicio
					if( servicioCotizacion.getTblServicio( ).getCveServicio( ) == cveServicio )
					{
						// en caso de que ya se encuentre el servicio
						// cambia bandera
						seEncuentra = true ;
						
						// asigna
						servicioEnCotizacion = servicioCotizacion ;
						
						// quiebra
						break ;
					}
				}
				
				// en caso de que se encuentre
				if( seEncuentra )
				{
					// guarda nueva CotizacionServicioWraper
					CotizacionServicioWraper cotizacionServicioWraper = new CotizacionServicioWraper( servicioEnCotizacion ) ;
					
					// agrega
					cotizacionWraper.addServicio( cotizacionServicioWraper ) ;
				}
				else
				{
					// guarda nueva CotizacionServicioWraper
					CotizacionServicioWraper cotizacionServicioWraper = new CotizacionServicioWraper( servicio ) ;
					
					// agrega
					cotizacionWraper.addServicio( cotizacionServicioWraper ) ;
				}
			}
			
			to.setCotizacion( cotizacion ) ;
			to.setCotizacionRealizada( cotizacionWraper ) ;
		}
		
		// extrae la tarea
		TblTarea tarea = tblTareaPreimplementacion.getTblTarea( ) ;
		
		// extrae la forma
		TblForma forma = tarea.getTblForma( ) ;
		
		// nombre del jsp
		String jspName = forma.getArchivoForma( ) ;
		// ruta completa del jsp
		URL ruta = null ;
		try
		{
			System.out.println( "@@@@@@@@@@@@@@@@@@@" + MCUtil.getFormsDirToDisplay( ) + System.getProperty( "file.separator" ) + jspName ) ;
			ruta = new URL( "file" , "localhost" , MCUtil.getFormsDirToDisplay( ) + System.getProperty( "file.separator" ) + jspName ) ;
			
			System.out.println( "@@@@@@@@@@@@@@@@@@@" + ruta ) ;
		}catch( Exception e )
		{
			e.printStackTrace( ) ;
			MasterCardDAO.closeEntityManager( ) ;
			return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_DATA_PROCESS_ERROR_OBTAINING_PATH , MCUtil.messages.getString( "com.mastercard.assets.web.errors.modules.flows.display.WorkFlowWorkFormErrorProcessingData.preimplementacion.ErrorCalculatingPath" , e.getMessage( ) ) , e ) ;
		}
		
//		String jspPath = ruta.getQuery( ) ;
		String jspPath = "/WEB-INF/formas/" + jspName ;
		
		System.out.println( "FlowUtil.java: jspPath/" + jspPath ) ;
		
		java.util.List< TblAsset > assets = new ArrayList< TblAsset >( ) ;
		java.util.List< TblAsset > assetsDelFlujo = tblPreimplementacion.getTblAssets( ) ;
		
		// recorre assets
		for( TblAsset asset1 : assetsDelFlujo )
			// en caso de que este activo
			if( asset1.getStatus( ) == 1 )
				assets.add( asset1 ) ;
		
		// coloca en el to
		to.setAssets( assets ) ;
		
		
		
		// abre el archivo
		File dir = new File( MCUtil.getFormsDir( ) ) ;
//		System.out.println( "***********" + dir.getAbsolutePath( ) ) ;
		File f = new File( dir , jspName ) ;
//		System.out.println( "***********" + f.getAbsolutePath( ) ) ;
		
//		System.getProperties( ).list( System.out ) ;
		
		String fileCode = "" ;
		StringBuffer sb = new StringBuffer( ) ;
		
		try
		{
			System.out.println( "PreimplementationPricesSendFormProcess.java: lecturaJSP/" ) ;
			BufferedReader rIn = new BufferedReader( new FileReader( f ) ) ;
			
			System.out.println( "PreimplementationPricesSendFormProcess.java: lecturaJSP/1" ) ;
			String line = "" ;
			
			System.out.println( "PreimplementationPricesSendFormProcess.java: lecturaJSP/2" ) ;
			while( ( line = rIn.readLine( ) ) != null )
				sb.append( line ) ;
			
			System.out.println( "PreimplementationPricesSendFormProcess.java: lecturaJSP/3" ) ;
			rIn.close( ) ;
			
			System.out.println( "PreimplementationPricesSendFormProcess.java: lecturaJSP/4" ) ;
		}catch( Exception e )
		{
			e.printStackTrace( ) ;
			MasterCardDAO.closeEntityManager( ) ;
			return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_DATA_PROCESS_NO_FORM_FILE_EXIST , MCUtil.messages.getString( "com.mastercard.assets.web.errors.modules.flows.display.WorkFlowWorkFormErrorProcessingData.preimplementacion.NoFormFileExist" , jspName ) , e ) ;
		}
		
		System.out.println( "PreimplementationPricesSendFormProcess.java: lecturaJSP/5" ) ;
//		System.out.println( sb.toString( ) ) ;
		
		// coloca la ruta del jsp
		to.setJspPath( jspPath ) ;
		to.setJspCode( sb.toString( ) ) ;
		
		sb.setLength( 0 ) ;
		sb = null ;
		
		System.out.println( "PreimplementationPricesSendFormProcess.java: to/" + to ) ;
		System.out.println( "PreimplementationPricesSendFormProcess.java: to.getError/" + to.getError( ) ) ;
		
                MasterCardDAO.closeEntityManager( ) ;
		return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_CAN_DISPLAY , to ) ;
	}
	
	public FlowProcessResult canDisplay( FlowProcessContext ctx )
	{
		TblTareaPreimplementacion tblTareaPreimplementacion = ctx.getTblTareaPreimplementacion( ) ;
		
		// en caso de uqe ya este ejecutado
		if( tblTareaPreimplementacion.getEjecutado( ) == 1 )
			return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_WORK_FLOW_EXECUTED ) ;
		
		// toma las clases para procesar la forma antes de desplegarla
		// toma la tarea
		TblTarea tarea = tblTareaPreimplementacion.getTblTarea( ) ;
		
		String nombreTarea = tarea.getNombre( ) ;
		
		// en caso de que la tarea haya sido desactivada
		if( tarea.getStatus( ) == 0 )
			return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_WORK_FLOW_WORK_DESACTIVATED ) ;
		
		// toma la forma a la que esta ligada la tarea
		TblForma forma = tarea.getTblForma( ) ;
		
		// en caso de que la forma este desactivada
		if( forma.getStatus( ) == 0 )
			return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_WORK_FLOW_WORK_FORM_DESACTIVATED ) ;
		
		/// se pueden agregar mas filtros
		
		return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_CAN_DISPLAY ) ;
	}
	
	public FlowProcessResult processExit( FlowProcessContext ctx )
		throws
			MasterCardException
	{
		HttpServletRequest request = ctx.getRequest( ) ;
		
		FlowProcessForm form = ctx.getForm( ) ;
		
		String salida = form.getExit( ) ;
		
		String comentarios = request.getParameter( "comentarios" ) ;
		
		// toma la clave de la tareapreimplementacion anterior
		String cveTareaPreimplementacionAnteriorParameter = request.getParameter( "cveTareaPreimplementacionAnterior" ) ;
		int cveTareaPreimplementacionAnterior = 0 ;
		
		// intenta cambiarlo
		try
		{
			cveTareaPreimplementacionAnterior = Integer.parseInt( cveTareaPreimplementacionAnteriorParameter ) ;
		}catch( Exception e )
		{
			return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_DATA_PROCESS_ERROR_RELOAD , MCUtil.messages.getString( "com.mastercard.assets.web.errors.modules.flows.display.WorkFlowWorkFormErrorProcessingData.preimplementacion.TareaPreimpelmentacionAnteriorNoEquivocado" ) , e ) ;
		}
		
		// toma la clave de la cotizacion
		String cveCotizacionParameter = request.getParameter( "cveCotizacion" ) ;
		int cveCotizacion = 0 ;
		
		// intenta cambiarlo
		try
		{
			cveCotizacion = Integer.parseInt( cveCotizacionParameter ) ;
		}catch( Exception e )
		{
			return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_DATA_PROCESS_ERROR_RELOAD , MCUtil.messages.getString( "com.mastercard.assets.web.errors.modules.flows.display.WorkFlowWorkFormErrorProcessingData.preimplementacion.NoCotizaExist" ) , e ) ;
		}
		
		int stepupResult = -1 ;
		
		// procesa los datos
		// los guarda en BD
		try
		{
			FormFile archivo = ( ( FlowProcessForm ) ctx.getUser( ).getAttribute( "FlowProcessForma" ) ).getArchivo01( ) ;
			
			System.out.println( "###3 FormFile: " + archivo ) ;
			
			byte[ ] fileData = new byte[ 0 ] ;
			String fileName = null ;
			
			// en caso de que no sea null
			if( archivo != null )
			{
				System.out.println( "###3 FormFile: " + archivo.getFileData( ) ) ;
				System.out.println( "###3 FormFile: " + archivo.getFileName( ) ) ;
				
				fileData = archivo.getFileData( ) ;
				fileName = archivo.getFileName( ) ;
			}
			
			stepupResult = MasterCardDAO.processCotizaServicioFormEmitirBoletos( ctx.getUser( ) , cveCotizacion , ctx.getTblTareaPreimplementacion( ) , fileData , fileName , comentarios , form.getExit( ) ) ;
		}catch( Exception e )
		{
                    MasterCardDAO.closeEntityManager( ) ;
			return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_DATA_PROCESS_ERROR_RELOAD , e.getMessage( ) , e ) ;
		}
		
                MasterCardDAO.closeEntityManager( ) ;
		return new FlowProcessResult( FlowUtil.FLOW_CONSTANTS_FORM_PROCESS_DATA_PROCESS_SUCCESS , stepupResult ) ;
	}
}
